package com.ilia.slitok;

import static com.ilia.slitok.Constants.NUMBER_OF_COORD;

import java.util.List;
import java.util.StringTokenizer;

import com.ilia.util.set.BitUtils;

public class Alloy {

  public long[] content_bits;
  public int[] coord;
  public int size;
  
  public Alloy(int id, int[] bars, List<Alloy> sourceBars) {
    this.content_bits = BitUtils.computeBinaryField(sourceBars.size(), bars);
    this.coord = Alloy.getCoords(bars, sourceBars);
    this.size = bars.length;
  }
  
  private Alloy() {
    
  }
  
  public int size() {
    return size;
  }
  
  public String toString() {
    int[] bars = BitUtils.computeRecords(content_bits);
    StringBuffer sb = new StringBuffer();
    int id = -1;
    if (bars.length==1) {
      id = bars[0];
      sb.append(id+".\t");
    }
    
    for (int i = 0; i < coord.length; i++) {
      sb.append(coord[i]+"\t");
    }
    sb.append(":");
    for (int i = 0; i < bars.length; i++) {
      if (i>0) {
        sb.append(" ");
      }
      sb.append(bars[i]);
    }
    return sb.toString();
  }
  
  
  public static Alloy xorNew(Alloy from, Alloy toremove) {
    Alloy a3 = new Alloy();
    a3.content_bits = BitUtils.xorBinaryField(from.content_bits, toremove.content_bits);
    a3.coord = new int[NUMBER_OF_COORD];
    for (int i = 0; i < NUMBER_OF_COORD; i++) {
      a3.coord[i] = from.coord[i] - toremove.coord[i];
    }
    return a3;
  }
  
  public static Alloy combineNew(Alloy a1, Alloy a2) {
    if (BitUtils.isOverlapping(a1.content_bits, a2.content_bits)) return null;
    Alloy a3 = new Alloy();
    a3.content_bits = BitUtils.orBinaryField(a1.content_bits, a2.content_bits);
    a3.coord = new int[NUMBER_OF_COORD];
    for (int i = 0; i < NUMBER_OF_COORD; i++) {
      a3.coord[i] = a1.coord[i] + a2.coord[i];
    }
    a3.size = a1.size + a2.size;
    return a3;
  }
  
  public static Alloy createFromString(String str, int source_size){ 
    Alloy alloy = new Alloy();
    
    StringTokenizer st = new StringTokenizer(str, ".\t #");
    alloy.coord = new int[NUMBER_OF_COORD];
    int i = 0;
    while (st.hasMoreTokens()) {
      try {
        String token = st.nextToken().trim();
        if (i==0) {
          int id = Integer.parseInt(token);
          alloy.content_bits = BitUtils.computeBinaryField(source_size, new int[] {id});
          
        } else if (i<5) {
          alloy.coord[i-1] = Integer.parseInt(token);
//        } else {
//          bar.desc = token;
        }
      }
      catch (NumberFormatException ex) {
        throw new RuntimeException(ex);
      }
      i++;
    }  
    
    alloy.size =1;
//  if (str.indexOf("#")>0) {
//  bar.desc = str.substring(str.indexOf("#")+1);
//} 
//if ("".equals(bar.desc)) {
//  bar.desc = null;
//}
    
    
    return alloy;
  }
  
  
  public static int[] getCoords(int[] bars, List<Alloy> source_bars) {
    int[] metals = new int[NUMBER_OF_COORD];
    for (int m = 0; m < metals.length; m++) {
      int mass = 0;
      for (int i : bars) {
        mass +=source_bars.get(i).coord[m];
      }
      metals[m] = mass;
    }
    return metals;
  }

}









